package com.token.sysflow.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.token.sysflow.core.AbstractFlowCore;
import com.token.sysflow.enumerate.ApprovalTypeEnum;
import com.token.sysflow.enumerate.FlowTypeEnum;
import com.token.sysflow.exception.ErrorCodeEnum;
import com.token.sysflow.exception.FlowException;
import com.token.sysflow.hander.ApproveProcess;
import lombok.Getter;
import lombok.Setter;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 处理参数bean
 * @author chenjianxiong 2020/4/13
 */
public abstract class AbstractFlowHandlerImpl implements FlowHandler {
    protected AbstractFlowCore flowCore;
    private final JSONObject inJson;
    private final JSONObject returnJson;

    /**
     * 单据关联Id
     */
    @Setter
    @Getter
    protected String keyUnid;

    /**
     * 流程单据号
     */
    @Setter
    @Getter
    private String flowNo;


    /**
     * 操作用户
     */
    @Getter
    @Setter
    private String actionUser;

    /**
     * 操作时间
     */
    @Getter
    @Setter
    private String actionTimer;

    /**
     * 租户Id
     */
    @Getter
    @Setter
    private int sysId;

    /**
     * 审批意见
     */
    @Setter
    @Getter
    private String opinions;

    /**
     * 表单字段
     */
    @Setter
    @Getter
    private JSONObject fieldValues;
    /**
     *
     */
    public AbstractFlowHandlerImpl(){
        inJson = new JSONObject();
        returnJson = new JSONObject();
        returnJson.put("code", ErrorCodeEnum.SUCCESS.getCode());
        returnJson.put("message", ErrorCodeEnum.SUCCESS.getDesc());
    }

    /**
     *
     * @throws Exception
     */
    public void handleReturnResult() throws Exception{
        ApproveProcess process = flowCore.getApproveProcess();

        this.setFlowNo(process.getFlowNo()); //用于回写提交日志。
        if(FlowTypeEnum.MAIN_FLOW.getId() == process.getFlowType()) {
            this.setReturnJson("keyUnid", process.getKeyUnid()); //主流程KeyUnid
        }else{
            this.setReturnJson("keyUnid", process.getParentId()); //主流程KeyUnid
        }
        this.setReturnJson("isReturned",process.getIsReturned());
        this.setReturnJson("flowStatus",process.getFlowStatus());
        this.setReturnJson("approvalType",process.getApprovalType());
        this.setReturnJson("flowNo",process.getFlowNo());
        this.setReturnJson("approvalText", ApprovalTypeEnum.getNameByValue(process.getApprovalType()));
        this.setReturnJson("flowType",process.getFlowType()); //1 main, 2 sub
        //------上面是主流程信息--------
        this.setReturnJson("flowData",process.getFlowProcessInfo());

    }

    /**
     * 代码程序错误输出
     * @param e
     */
    public void handleReturnErr(Exception e){
        returnJson.put("code", ErrorCodeEnum.FAILED.getCode());
        String message = e.getMessage();
        if(message == null){
            message = e.toString();
        }
        returnJson.put("message",message);
        if(flowCore != null) {
            this.setFlowNo(flowCore.updateApproveProcessErr(ErrorCodeEnum.FAILED.getCode(), e.toString()));
        }
    }

    /**
     * 业务、逻辑、参数等错误输出
     * @param e
     */
    public void handleReturnErr(FlowException e){
        returnJson.put("code", e.getErrCode());
        returnJson.put("message",e.getMessage());
        if(flowCore != null) {
            this.setFlowNo(flowCore.updateApproveProcessErr(ErrorCodeEnum.FAILED.getCode(), e.getMessage()));
        }
    }


    /**
     *
     * @param keyName
     * @param json
     */
    protected void setReturnJson(String keyName,JSONObject json){
        this.returnJson.put(keyName,json);
    }

    /**
     *
     * @param keyName
     * @param json
     */
    protected void setReturnJson(String keyName, JSONArray json){
        this.returnJson.put(keyName,json);
    }
    /**
     *
     * @param keyName
     * @param value
     */
    protected void setReturnJson(String keyName,String value){
        this.returnJson.put(keyName,value);
    }

    /**
     *
     * @param keyName
     * @param value
     */
    protected void setReturnJson(String keyName,int value){
        this.returnJson.put(keyName,value);
    }


    /**
     * 返回Json
     * @return
     */
    public JSONObject getResult(){
        return this.returnJson;
    }

    /**
     *
     * @return
     */
    public JSONObject getInParamJson(){
        return this.inJson;
    }

    /**
     * 把传入参数写入JSON
     */
    public void writeInJson() {
        Object o = this;
        Class<?> c = o.getClass();
        while (!c.getName().equals("java.lang.Object")) {
            writeInJson(c, o);
            c = c.getSuperclass();
        }
    }
    /**
     * 把传入参数写入JSON
     * @param c
     * @param o
     */
    private void writeInJson(Class<?> c,Object o){
        Field[] fields = c.getDeclaredFields();
//        System.out.println("fields = " + c.getName());
        for (Field field : fields) {
            String filedName = field.getName();

            if("inJson".equalsIgnoreCase(filedName) || "returnJson".equalsIgnoreCase(filedName)){
                continue;
            }
            try {
                String firstLetter = filedName.substring(0, 1).toUpperCase();
                String getter = "get" + firstLetter + filedName.substring(1);
                Method method = c.getMethod(getter);
                Object value = method.invoke(o);
                inJson.put(filedName,value);
            }catch (Exception e){
//                System.out.println("--->无函数：" + filedName);
            }
        }
    }



    /**
     * 提交处理
     *
     * @return true 处理成功
     * @throws Exception 抛出错误
     */
    public boolean submitHandler() throws Exception{
        if(flowCore != null) { //读取数据类，flowCore 可能为空值
            flowCore.execute(this);
        }
        //处理返回参数
        handleReturnResult();
        return true;
    }
    /**
     * 关闭
     */
    public void close() {
        if(flowCore != null) {
            flowCore.close();
        }
    }
}
